//vm : MVVM的实例对象
//exp: 表达式
//cb : 握有更新器的回调
function Watcher(vm, exp, cb) {
    //this:Watcher对应的实例对象
    this.cb = cb;
    this.vm = vm;
    this.exp = exp;
    //depIds 是一个对象
    this.depIds = {};
    this.value = this.get();
}

Watcher.prototype = {
    update: function() {
        this.run();
    },
    run: function() {
        var value = this.get();
        var oldVal = this.value;
        if (value !== oldVal) {
            this.value = value;
            //dep发现自己的值要产生改变 会通知到它对应的所有watcher来调用自己的更新器
            this.cb.call(this.vm, value, oldVal);
        }
    },
    addDep: function(dep) {
        //this : {{}}.watcher
        if (!this.depIds.hasOwnProperty(dep.id)) {
            //构建1个dep对应多个watcher
            dep.addSub(this);
            //构建 1个watcher对应多个dep
            this.depIds[dep.id] = dep;
        }
    },
    get: function() {
        //this watcher对象
        Dep.target = this;//打开数据劫持时get方法的开关
        var value = this.getVMVal();
        Dep.target = null;//关掉数据劫持时get方法的开关
        return value;
    },

    getVMVal: function() {
        //[a,b,msg]
        var exp = this.exp.split('.');
        //data数据
        var val = this.vm._data;
        exp.forEach(function(k) {
            //访问data数据
            //a b msg所对应的get方法都会被调用
            val = val[k];
        });
        return val;
    }
};